
/*
 * The Real SoundTracker - module info page
 *
 * Copyright (C) 1998-2001 Michael Krause
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 */

#include <stdio.h>
#include <string.h>

// #include <gtk/gtkfeatures.h>

#include "i18n.h"
#include "module-info.h"
#include "gui.h"
#include "gui-subs.h"
#include "xm.h"
#include "st-subs.h"
#include "main.h"
#include "sample-editor.h"
#include "instrument-editor.h"
#include "keys.h"
#include "track-editor.h"

static GtkWidget *ilist, *slist, *songname;
static GtkWidget *freqmode_w[2], *ptmode_toggle;
static gint curi = 0, curs = 0;

static void ptmode_changed (GtkWidget *widget){
	gint m = GTK_TOGGLE_BUTTON(widget)->active;
	if(xm) {
		xm->flags &= ~XM_FLAGS_IS_MOD;
		xm->flags |= m * XM_FLAGS_IS_MOD;
	}
	xm_set_modified(1);
}

static void freqmode_changed (void){
	gint m = find_current_toggle(freqmode_w, 2);
	if(xm) {
		xm->flags &= ~XM_FLAGS_AMIGA_FREQ;
		xm->flags |= m * XM_FLAGS_AMIGA_FREQ;
	}
	xm_set_modified(1);
}

static void songname_changed (GtkEntry *entry){
	strncpy(xm->name, gtk_entry_get_text(entry), 20);
	xm->name[20] = 0;
	xm_set_modified(1);
}

void modinfo_page_create (GtkNotebook *nb){
	GtkWidget *hbox, *thing, *vbox;
/*    gchar *ititles[3] = { "n", _("Instrument Name"), _("#smpl") };
    gchar *stitles[2] = { "n", _("Sample Name") };*/
	static const gchar *freqlabels[] = { N_("Linear"), N_("Amiga"), NULL };
	gchar buf[5];
	gchar *insertbuf[3] = { buf, "", "0" };
	gint i;

	hbox = gtk_hbox_new(TRUE, 10);
	gtk_container_border_width(GTK_CONTAINER(hbox), 10);
	gtk_notebook_append_page(nb, hbox, gtk_label_new(_("Module Info")));
	gtk_widget_show(hbox);

	vbox = gtk_vbox_new(FALSE, 2);
	gtk_box_pack_start(GTK_BOX(hbox), vbox, TRUE, TRUE, 0);
	gtk_widget_show(vbox);

	hbox = gtk_hbox_new(FALSE, 4);
	gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, TRUE, 0);
	gtk_widget_show(hbox);

	thing = gtk_label_new(_("Songname:"));
	gtk_box_pack_start(GTK_BOX(hbox), thing, FALSE, TRUE, 0);
	gtk_widget_show(thing);

	gui_get_text_entry(20, songname_changed, &songname);
	gtk_box_pack_start(GTK_BOX(hbox), songname, TRUE, TRUE, 0);
	g_signal_connect_after(G_OBJECT(songname), "changed", G_CALLBACK(songname_changed), NULL);
	gtk_widget_show(songname);

	hbox = gtk_hbox_new(FALSE, 4);
	gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, TRUE, 0);
	gtk_widget_show(hbox);

	add_empty_hbox(hbox);
	thing = make_labelled_radio_group_box(_("Frequencies:"), freqlabels, freqmode_w, freqmode_changed);
	gtk_widget_show(thing);
	gtk_box_pack_start(GTK_BOX(hbox), thing, FALSE, TRUE, 0);
	add_empty_hbox(hbox);

	ptmode_toggle = gtk_check_button_new_with_label(_("ProTracker Mode"));
	gtk_box_pack_start(GTK_BOX(hbox), ptmode_toggle, FALSE, TRUE, 0);
	gtk_widget_show(ptmode_toggle);
	g_signal_connect (G_OBJECT(ptmode_toggle), "toggled", G_CALLBACK(ptmode_changed), NULL);

	add_empty_hbox(hbox);

}

void modinfo_delete_unused_instruments (void){
	gint i;

	for(i = 0; i < sizeof(xm->instruments) / sizeof(xm->instruments[0]); i++) {
		if(!st_instrument_used_in_song(xm, i + 1)) {
			st_clean_instrument(&xm->instruments[i], NULL);
			xm_set_modified(1);
		}
	}

	sample_editor_update();
	instrument_editor_update();
	modinfo_update_all();
}

gboolean modinfo_page_handle_keys (gint shift, gint ctrl, gint alt, guint32 keyval, gboolean pressed) {
	gint i;

	i = keys_get_key_meaning(keyval, ENCODE_MODIFIERS(shift, ctrl, alt));
	if(i != -1 && KEYS_MEANING_TYPE(i) == KEYS_MEANING_NOTE) {
		track_editor_do_the_note_key(i, pressed, keyval, ENCODE_MODIFIERS(shift, ctrl, alt));
		return TRUE;
	}
	return FALSE;
}


void modinfo_update_all (void){
	gint i;
	gint m = xm_get_modified();

//     for(i = 0; i < 128; i++)
// 	modinfo_update_instrument(i);
	gtk_entry_set_text(GTK_ENTRY(songname), xm->name);
	gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(ptmode_toggle), xm->flags & XM_FLAGS_IS_MOD);
	gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(freqmode_w[xm->flags & XM_FLAGS_AMIGA_FREQ]), TRUE);
	xm_set_modified(m);
}

void modinfo_find_unused_pattern (void){
	gint n = st_find_first_unused_and_empty_pattern(xm);
	printf("%d\n", n);
	if(n != -1) gui_set_current_pattern(n);
}

void modinfo_copy_to_unused_pattern (void){
	gint n = st_find_first_unused_and_empty_pattern(xm);
	gint c = gui_get_current_pattern();
	if(n != -1 && !st_is_empty_pattern(&xm->patterns[c])) {
		gui_play_stop();
		st_copy_pattern(&xm->patterns[n], &xm->patterns[c]);
		xm_set_modified(1);
		gui_set_current_pattern(n);
	}
}

// Move unused patterns to the end of the pattern space
void modinfo_pack_patterns (void){
	gint i, j, last, used;

    // Get number of last used pattern and number of used patterns
	for(i = 0, last = 0, used = 0; i < sizeof(xm->patterns) / sizeof(xm->patterns[0]); i++) {
		if(st_is_pattern_used_in_song(xm, i)) {
			last = i;
			used++;
		}
	}

    // Put unused patterns to the end
	for(i = 0; i < used; ) {
		if(!st_is_pattern_used_in_song(xm, i)) {
			for(j = i; j < last; j++) st_exchange_patterns(xm, j, j + 1);
		} 
		else {
			i++;
		}
	}
	gui_playlist_initialize();
	xm_set_modified(1);
}

// Put patterns in playback order, move unused patterns to the end of the pattern space
void modinfo_reorder_patterns (void){
	modinfo_pack_patterns();
	xm_set_modified(1);
}

// Clear patterns which are not in the playlist
void modinfo_clear_unused_patterns (void){
	gint i;
	for(i = 0; i < sizeof(xm->patterns) / sizeof(xm->patterns[0]); i++)
	if(!st_is_pattern_used_in_song(xm, i)) st_clear_pattern(&xm->patterns[i]);
	tracker_redraw(tracker);
	xm_set_modified(1);
}

// Optimize -- clear everything unused

static void modinfo_optimize_module_callback (gint reply, gpointer data){
	if(reply == 0) {
		modinfo_clear_unused_patterns();
		modinfo_delete_unused_instruments();
		modinfo_reorder_patterns();
		xm_set_modified(1);
	}
}

void modinfo_optimize_module (void){
	gchar infbuf[512];
	gint a, b, c, d, e;

	d = sizeof(xm->patterns) / sizeof(xm->patterns[0]);
	e = sizeof(xm->instruments) / sizeof(xm->instruments[0]);
	for(a = 0, b = 0, c = 0; a < d; a++) {
		if(!st_is_pattern_used_in_song(xm, a))
			b++;
			if(a<e) if(!st_instrument_used_in_song(xm, a + 1)) c++;
	}

	sprintf(infbuf, _("Unused patterns: %d (used: %d)\nUnused instruments: %d (used: %d)\n\nClear unused and reorder playlist?\n"), b, d-b, c, e-c);

	gnome_app_ok_cancel_modal(GNOME_APP(mainwindow), infbuf, modinfo_optimize_module_callback, NULL);

}

